package com.citywithincity.db.data2db;

import java.io.ByteArrayInputStream;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.rowset.serial.SerialBlob;

import com.citywithincity.db.interfaces.IPsSetter;
import com.citywithincity.utils.IoUtil;

public class Data2DbCreator {
	
	static class byteArray2Blob implements IPsSetter{

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			if(value==null){
				ps.setObject(index, null);
			}else{
				byte[] string = (byte[]) value;
				ByteArrayInputStream inputStream = null;
				try{
					inputStream = new ByteArrayInputStream(string);
					ps.setBinaryStream(index, inputStream,string.length );
				}finally{
					IoUtil.close(inputStream);
				}
				
			}
		}
		
	}
	
	static class boolean2BigDecimal implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			ps.setObject(index, ((Boolean) value) ? 1 : 0);
		}

	}

	static class boolean2Integer implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			ps.setInt(index, ((Boolean) value) ? 1 : 0);
		}

	}

	static class byte2Blob implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			if (value == null) {
				ps.setObject(index, null);
			} else {
				byte[] bytes = (byte[]) value;
				ps.setBlob(index, new SerialBlob(bytes));
			}

		}

	}

	static class double2BigDecimal implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			ps.setObject(index, value);
		}

	}

	static class double2String implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			ps.setObject(index, value);
		}

	}

	static class int2BigDecimal implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			ps.setObject(index, value);
		}

	}

	static class int2Double implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			ps.setObject(index, value);
		}

	}

	static class int2String implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			ps.setString(index, String.valueOf(value));
		}

	}

	static class long2BigDecimal implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			ps.setObject(index, value);
		}

	}
	static class long2Integer implements IPsSetter {

		@Override
		public void setValue(PreparedStatement ps, int index, Object value) throws SQLException {
			ps.setLong(index, (Long)value);
		}

	}
	public static IPsSetter create(Class<?> fieldClass, Class<?> columnClass) throws Exception {

		char c = fieldClass.getSimpleName().charAt(0);
		String clazzEntityToDb = null;
		if (c >= 'a' && c <= 'z') {
			clazzEntityToDb = "com.citywithincity.db.data2db.Data2DbCreator$" + fieldClass.getSimpleName() + "2"
					+ columnClass.getSimpleName();
		} else {
			clazzEntityToDb = "com.citywithincity.db.data2db." + fieldClass.getSimpleName() + "2"
					+ columnClass.getSimpleName();
		}

		clazzEntityToDb = clazzEntityToDb.replace("[]", "Array");
		return create(clazzEntityToDb);
	}
	
	private static Map<Class<?>, IPsSetter> map = new HashMap<Class<?>, IPsSetter>();
	
	public static IPsSetter create(String name) throws Exception {
		Class<?> clazz = Class.forName(name);
		IPsSetter valueConvert = map.get(clazz);
		if(valueConvert==null){
			valueConvert = (IPsSetter) clazz.newInstance();
			map.put(clazz, valueConvert);
		}
		return valueConvert;
	}
}
